﻿using FadeJSON;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace WorkWeiXin.Winforms
{
    class AccessTokenFileCache : Work.Weixin.IAccessTokenCache
    {
        private DateTime writeTime;
        private string jsonContent;

        private AccessTokenFileCache(string appName)
        {
            this.AppName = appName;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="appName">不包括扩展名</param>
        /// <returns></returns>
        public static AccessTokenFileCache Load(string appName)
        {
            var cache = new AccessTokenFileCache(appName);

            var filename = appName + ".tmp";
            if (!File.Exists(filename))
            {
                cache.writeTime = DateTime.MinValue;
                cache.jsonContent = "{"
                    + "\"errcode\": 0,"
                    + "\"errmsg\": \"ok\","
                    + "\"access_token\": \"accesstoken000001\","
                    + "\"expires_in\": 7200"
                    + "}";
                WriteFile(filename, cache.jsonContent, cache.writeTime);
            }
            else
            {
                DateTime time;
                string jsonContent = ReadFile(filename, out time);
                cache.writeTime = time;
                cache.jsonContent = jsonContent;
            }

            return cache;
        }

        public override string ToString()
        {
            return string.Format("<{0}>[{1}]", writeTime, jsonContent);
        }

        static readonly char[] separator = new char[] { '【', '】' };
        private static string ReadFile(string filename, out DateTime getTime)
        {
            var strJson = string.Empty;
            getTime = DateTime.MinValue;

            string content = File.ReadAllText(filename);
            string[] parts = content.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            getTime = DateTime.Parse(parts[0]);
            strJson = parts[1];

            return strJson;
        }

        #region IAccessTokenCache 成员

        public string AppName { get; private set; }

        /// <summary>
        /// 尝试获取<paramref name="access_token"/>。
        /// </summary>
        /// <param name="expired_time">缓存的有效期是多少秒</param>
        /// <param name="access_token"></param>
        /// <returns></returns>
        public bool TryGetAccessToken(int expired_time, out string access_token)
        {
            bool success = false;
            if (DateTime.Now.Subtract(this.writeTime).TotalMinutes < expired_time) // 2 hours max
            {
                JsonBaseType jsonObj = Json.FromString(this.jsonContent);
                access_token = jsonObj.Value["access_token"].Value;
                success = true;
            }
            else
            {
                access_token = string.Empty;
            }

            return success;
        }

        /// <summary>
        /// 更新缓存
        /// </summary>
        /// <param name="content">更新后的内容</param>
        /// <param name="time">何时更新的？</param>
        public void UpdateCache(string content, DateTime time)
        {
            this.writeTime = time;
            this.jsonContent = content;

            var filename = this.AppName + ".tmp";
            WriteFile(filename, content, time);
        }

        private static void WriteFile(string filename, string content, DateTime time)
        {
            File.WriteAllText(filename,
                string.Format("【{0}】【{1}】", time, content));
        }

        #endregion

    }
}
